package cc.siyecao.fastdfs.command.storage;

import cc.siyecao.fastdfs.model.RecvPackageInfo;
import cc.siyecao.fastdfs.protocol.ProtocolConstants;
import cc.siyecao.fastdfs.uploader.Uploader;
import cc.siyecao.fastdfs.util.BytesUtil;
import cc.siyecao.fastdfs.util.ProtocolUtil;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;

/**
 * 添加文件命令
 *
 * @author lyt
 */
public class AppendFileCommand extends FdfsStorageCommand<Integer> {
    public AppendFileCommand(String groupName, String appenderFileName, long fileSize, Uploader uploader) {
        this.groupName = groupName;
        this.fileName = appenderFileName;
        this.fileSize = fileSize;
        this.uploader = uploader;
    }

    @Override
    protected void send(OutputStream out, Charset charset) throws Exception {
        byte[] header;
        byte[] hexLenBytes;
        byte[] fileNameBytes;
        int offset;
        long bodyLen;
        fileNameBytes = fileName.getBytes( charset );
        bodyLen = 2 * ProtocolConstants.FDFS_PROTO_PKG_LEN_SIZE + fileNameBytes.length + fileSize;

        header = ProtocolUtil.packHeader( STORAGE_PROTO_CMD_APPEND_FILE, bodyLen, (byte) 0 );
        byte[] wholePkg = new byte[(int) (header.length + bodyLen - fileSize)];
        System.arraycopy( header, 0, wholePkg, 0, header.length );
        offset = header.length;

        hexLenBytes = BytesUtil.long2buff( fileName.length() );
        System.arraycopy( hexLenBytes, 0, wholePkg, offset, hexLenBytes.length );
        offset += hexLenBytes.length;

        hexLenBytes = BytesUtil.long2buff( fileSize );
        System.arraycopy( hexLenBytes, 0, wholePkg, offset, hexLenBytes.length );
        offset += hexLenBytes.length;

        System.arraycopy( fileNameBytes, 0, wholePkg, offset, fileNameBytes.length );
        offset += fileNameBytes.length;
        out.write( wholePkg );
        uploader.upload( out );
    }

    @Override
    protected Integer receive(InputStream in, Charset charset) throws Exception {
        RecvPackageInfo pkgInfo = ProtocolUtil.recvPackage( in, STORAGE_PROTO_CMD_RESP, 0 );
        this.errno = pkgInfo.errno;
        if (pkgInfo.errno != 0) {
            return Integer.valueOf( this.errno );
        }
        return 0;
    }
}
